/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef __RC4_H__
#define __RC4_H__

class RC4
{
	unsigned char state[256];
	unsigned char x;
	unsigned char y;

	void prepare_key(const unsigned char * key_data_ptr, int key_data_len)
	{
		for(int counter = 0; counter < 256; counter++)
			state[counter] = counter;
		x = 0;
		y = 0;
		unsigned char index1 = 0;
		unsigned char index2 = 0;
		for(int counter = 0; counter < 256; counter++)
		{
			index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
			std::swap(state[counter], state[index2]);

			index1 = (index1 + 1) % key_data_len;
		}
	}
public:
	RC4(const char * key_data_ptr, int key_data_len)
	{
		prepare_key(reinterpret_cast<const unsigned char *>(key_data_ptr), key_data_len);
	}
	RC4(const char * key_data_ptr)
	{
		prepare_key(reinterpret_cast<const unsigned char *>(key_data_ptr), strlen(key_data_ptr));
	}
	void rc4(char * buffer_ptr, int buffer_len)
	{
		for(int counter = 0; counter < buffer_len; counter ++)
		{
			x = (x + 1) % 256;
			y = (state[x] + y) % 256;
			std::swap(state[x], state[y]);

			unsigned char xorIndex = (state[x] + state[y]) % 256;

			if( buffer_ptr )
				buffer_ptr[counter] ^= state[xorIndex];
		}
	}
};


#endif // __RC4_H__

